"""
请求处理工具类
"""
import json

import requests
from loguru import logger

from api_test_framework.utils.handle_extract import extract_response_to_env
from api_test_framework.utils.handle_path import PathHandler
from api_test_framework.utils.handle_presql import pre_sql
from api_test_framework.utils.handle_replace import replace_mark_data


def requests_api(case, token=None):
    method = case["请求方法"]
    url = case["接口地址"]
    param = case["请求参数"]
    header = case["请求头"]
    presql_raw = case["前置SQL"]

    # 替换url、param、header、presql中的mark数据，有些用例数据里有mark值标记/mark函數标记
    # - 替换接口地址里的mark数据
    url = replace_mark_data(url)
    # - 在执行前置SQL之前替换sql里mark数据，返回替换后的可执行的sql语句
    presql = replace_mark_data(presql_raw)
    # - 执行前置SQL方法 把执行sql语句后的结果存到环境变量
    pre_sql(presql)
    # - 替换请求头、请求参数中的mark数据
    header = replace_mark_data(header)
    param = replace_mark_data(param)

    # 发送接口请求之前，头部和参数需要做反序列操作 转化为字典
    # 如果某些用例头部和参数为空，读取出来是None，不能进行反序列化操作；-- 判空处理
    if param is not None:
        param = json.loads(param)  # 字典
    if header is not None:
        header = json.loads(header)  # 字典
        if token is not None:
            header["Authorization"] = token  # key存在就是替换value，可以不存在，那就是新增键值对

    logger.info("=================请求消息==========================")
    logger.info(f"请求方法是：{method}")
    logger.info(f"请求地址是：{url}")
    logger.info(f"请求参数是：{param}")
    logger.info(f"请求头部是：{header}")

    # 因为我们这个函数需要覆盖get post put等各种请求方法处理，所以通过不同分支判断处理：
    resp = None  # 初始化resp
    if method.lower() == "get":  # excel表格里写的方法大小写可能不一样，所以统一化大小写再判断
        # 发送get请求
        resp = requests.request(method, url, headers=header, params=param)
    elif method.lower() == "post":
        # 发送post请求: 因为post请求content-type不一样，发送请求方式不一样的；分支判断
        if header["Content-Type"] == "application/json":
            resp = requests.request(method, url, headers=header, json=param)
        elif header["Content-Type"] == "application/x-www-form-urlencoded":
            resp = requests.request(method, url, headers=header, data=param)
        elif header["Content-Type"] == "multipart/form-data":
            header.pop("Content-Type")
            # 构建一个文件参数：param = {"filename":"code.png"}
            filename = param["filename"]  # "code.png"
            param_file = {"file": open(PathHandler.DATA_DIR / filename, mode="rb")}  # 图片路径+图片名字
            logger.info(f"文件参数：{param_file}")
            logger.info(f"文件上传的头部：{header}")
            resp = requests.request(method, url, headers=header, files=param_file)
    # 发送put请求 --后续遇到这种接口再实现
    elif method.lower() == "put":
        resp = requests.request(method, url, headers=header, json=param)
    # 设置返回值 返回响应结果消息对象
    logger.info("=====================响应消息========================")
    logger.info(f"响应状态码是：{resp.status_code}")
    logger.info(f"响应正文是：{resp.text}")

    # 提取响应字段，储存环境变量，用于后续接口请求
    extract_data = case["提取响应字段"]
    extract_response_to_env(resp, extract_data)
    return resp
